'''
copyright: Copyright (C) 2015-2024, Wazuh Inc.

           Created by Wazuh, Inc. <info@wazuh.com>.

           This program is free software; you can redistribute it and/or modify it under the terms of GPLv2

type: integration

brief: Wazuh is able to detect vulnerabilities in the applications installed in agents using the Vulnerability Detector
       module. This software audit is performed through the integration of vulnerability feeds indexed by Redhat,
       Canonical, Debian, Amazon Linux and NVD Database.

components:
    - vulnerability_detector

suite: feeds

targets:
    - manager

daemons:
    - wazuh-modulesd

os_platform:
    - linux

os_version:
    - Arch Linux
    - Amazon Linux 2022
    - Amazon Linux 2
    - Amazon Linux 1
    - CentOS 8
    - CentOS 7
    - Debian Buster
    - Red Hat 8
    - Ubuntu Trusty
    - Ubuntu Xenial
    - Ubuntu Bionic
    - Ubuntu Focal
    - Ubuntu Jammy
    - SUSE Linux Enterprise Desktop 15

references:
    - https://documentation.wazuh.com/current/user-manual/capabilities/vulnerability-detection/index.html

tags:
    - vulnerability_detector
    - feeds
'''
import pytest
import json
from pathlib import Path

from wazuh_testing.constants.daemons import ANALYSISD_DAEMON, MODULES_DAEMON, SYSCHECK_DAEMON
from wazuh_testing.constants.paths.logs import WAZUH_LOG_PATH
from wazuh_testing.utils.services import check_if_process_is_running
from wazuh_testing.utils.callbacks import generate_callback
from wazuh_testing.utils.file import read_yaml
from wazuh_testing.tools.monitors.file_monitor import FileMonitor
from wazuh_testing.utils.db_queries.cve_db import get_rows_number
from wazuh_testing.utils.configuration import get_test_cases_data
from wazuh_testing.modules.modulesd.vulnerability_detector import patterns as cb
from wazuh_testing.modules.modulesd.configuration import MODULESD_DEBUG
from wazuh_testing.modules.monitord.configuration import MONITORD_ROTATE_LOG
from . import TEST_CASES_PATH, CONFIGURATIONS_PATH


pytest.skip("The tests will be deprecated, they test the old Vulnerability Detector.", allow_module_level=True)

# Variables
pytestmark = [pytest.mark.server]
local_internal_options = {MODULESD_DEBUG: '2', MONITORD_ROTATE_LOG: '0'}
daemons_handler_configuration = {'daemons': [ANALYSISD_DAEMON, MODULES_DAEMON, SYSCHECK_DAEMON]}

# Configuration and cases data
configurations_path = Path(CONFIGURATIONS_PATH, 'configuration_import_invalid_feed_type.yaml')
cases_path = Path(TEST_CASES_PATH, 'cases_import_invalid_feed_type.yaml')

# test_import_invalid_feed_type configurations
configurations = read_yaml(configurations_path)
metadata = [item['metadata'] for item in read_yaml(cases_path)]
_, configuration_metadata, case_ids = get_test_cases_data(cases_path)

# In this test module, we do not build configurations via use cases, but we build them separately
if len(configurations) != len(metadata):
    raise ValueError(f"Number of configurations must be the same than the use cases. {len(configurations)} "
                     f"!= {len(metadata)}")

# Replace custom feed URL tags in configurations
for index, (configuration, use_case) in enumerate(zip(configurations, metadata)):
    configurations[index] = json.loads(json.dumps(configuration).replace('CUSTOM_FEED_URL',
                                                                         use_case['custom_feed_url']))


@pytest.mark.tier(level=2)
@pytest.mark.parametrize('test_configuration, test_metadata', zip(configurations, configuration_metadata), ids=case_ids)
def test_import_invalid_feed_type(test_configuration, test_metadata, set_wazuh_configuration, truncate_monitored_files,
                                  configure_local_internal_options, clean_cve_tables, daemons_handler):
    '''
    description: Check the vulnerability detector behavior when importing unexpected file types as feeds.

    test_phases:
        - setup:
            - Set a custom Wazuh configuration, with custom URL feeds which refer to files of unexpected type.
            - Configure custom local_internal_options.
            - Truncate wazuh logs.
            - Restart wazuh-modulesd daemon to apply configuration changes.
        - test:
            - Check the error when updating the provider data.
            - Check the error when updating the CVE database.
            - Check that no junk data has been inserted into the database.
            - Check that wazuh-modulesd is running (it has not crashed after parsing unexpected file types).
        - teardown:
            - Truncate wazuh logs.
            - Restore initial configuration, both ossec.conf and local_internal_options.conf.
    test_phases:

    wazuh_min_version: 4.4.0

    tier: 2

    parameters:
        - test_configuration:
            type: dict
            brief: Configuration loaded from `configuration_template`.
        - test_metadata:
            type: dict
            brief: Test case metadata.
        - set_wazuh_configuration:
            type: fixture
            brief: Set wazuh configuration.
        - configure_local_internal_options:
            type: fixture
            brief: Set local_internal_options configuration.
        - truncate_monitored_files:
            type: fixture
            brief: Truncate all the log files and json alerts files before and after the test execution.
        - clean_cve_tables:
            type: fixture
            brief: Clean all CVE tables.
        - daemons_handler:
            type: fixture
            brief: Restart wazuh-modulesd daemon before starting a test, and stop it after finishing.

    assertions:
        - Check the error when updating the provider database.
        - Check the error when updating the CVE database.
        - Check that no junk data has been inserted into the database.
        - Check that wazuh-modulesd is running (it has not crashed after parsing unexpected file types).

    input_description:
        - The `configuration_import_invalid_feed_type.yaml` file provides the module configuration for this test.
        - The `cases_import_invalid_feed_type` file provides the test cases.

    expected_output:
        - r"Failed when updating '{provider_feed_name}' database"
        - r"ERROR: .* CVE database could not be updated."
    '''
    file_monitor = FileMonitor(WAZUH_LOG_PATH)

    if test_metadata['target'] == 'nvd':
        pytest.xfail(reason='no error reported when importing invalid NVD feed. '
                            'https://github.com/wazuh/wazuh/issues/5210')

    # Check in log that the provider database could not be updated
    for provider_feed_name in test_metadata['provider_feed_names']:
        file_monitor.start(callback=generate_callback(regex=cb.DATABASE_UPDATE_FAILED,
                                                      replacement={'provider_feed_name': provider_feed_name}),
                           timeout=20)
        assert file_monitor.callback_result is not None, f"Did not find expected '{cb.DATABASE_UPDATE_FAILED}' log"

    # Check the general error when updating the CVE database
    file_monitor.start(timeout=20, callback=generate_callback(regex=cb.CVE_DATABASE_UPDATE_ERROR))
    assert file_monitor.callback_result is not None, f"Did not find expected '{cb.DATABASE_UPDATE_FAILED}' log."

    # Check that no junk data has been inserted in the DB
    if test_metadata['target'] == 'msu':
        assert get_rows_number('MSU') == 0
    elif test_metadata['target'] == 'nvd':
        assert get_rows_number('NVD_CVE') == 0
    else:
        assert get_rows_number('VULNERABILITIES') == 0

    # Check that wazuh-modulesd is running and has not crashed when trying to parse files with unexpected file types
    assert check_if_process_is_running(MODULES_DAEMON), 'wazuh-modulesd is not running. It may have crashed'
